<!doctype html>
<html lang="zh-cn">
    <head>
        <meta charset="UTF-8" />
        <title>字体分包构建报告</title>
        <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
        <link
            rel="stylesheet"
            href="https://fastly.jsdelivr.net/npm/vant@4.9.15/lib/index.css"
        />
        <link
            href="https://unpkg.com/vue3-easy-data-table@1.5.47/dist/style.css"
            rel="stylesheet"
        />
        <link rel="stylesheet" href="./result.css" />
        <style>
            body {
                overflow-wrap: break-word;
                font-size: 18px;
                background-color: #edf0f3;
                --easy-table-border: 0;
            }
            main {
                padding: 20px;
                margin-top: var(--van-nav-bar-height);
                margin-bottom: var(--van-tabbar-height);
            }
            .light-blue {
                --easy-table-body-row-font-color: #427cb7;
            }
            .light-red {
                --easy-table-body-row-font-color: #b74273;
            }
            .hint {
                display: block;
                text-align: center;
                color: gray;
                margin: 1rem;
            }
            .scroller {
                height: 100%;
            }

            .user {
                height: 32%;
                padding: 0 12px;
                display: flex;
                align-items: center;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <van-nav-bar
                :title="reporter.state?.css?.family +' 分包报告'"
                right-text="Github"
                @click-right="toGithub"
                style="position: fixed; width: 100%; top: 0"
            ></van-nav-bar>
            <div v-if="reporter.isLoading">加载中</div>
            <div v-if="reporter.isError">加载错误</div>

            <main :style="style">
                <van-cell-group inset title="样式控制">
                    <van-field
                        v-model="fontSize"
                        label="字体大小"
                        placeholder="请输入字体大小"
                    ></van-field>
                    <van-field
                        v-model="fontWeight"
                        label="字体重量"
                        placeholder="请输入字重"
                    ></van-field>
                </van-cell-group>
                <!-- 汇总信息 -->
                <display-chart
                    v-if="reporter.isOk() && activePage === 0"
                    :reporter="reporter.state"
                ></display-chart>
                <!-- 字体信息表格 -->
                <name-table
                    v-if="reporter.isOk() && activePage === 1"
                    :reporter="reporter.state"
                ></name-table>
                <!-- 单包查询 -->
                <pkg-list
                    v-if="reporter.isOk() && activePage === 2"
                    :reporter="reporter.state"
                ></pkg-list>
                <div class="hint">
                    <a href="https://chinese-font.netlify.app">中文网字计划</a>
                    <span> cn-font-split 生成 </span>
                </div>
            </main>

            <!-- 底部导航栏 -->
            <van-tabbar v-model="activePage">
                <van-tabbar-item icon="home-o">汇总</van-tabbar-item>
                <van-tabbar-item icon="home-o">字体信息</van-tabbar-item>
                <van-tabbar-item icon="search">分包</van-tabbar-item>
            </van-tabbar>
        </div>
    </body>
    <script src="https://unpkg.com/vue@3.4.33"></script>
    <script src="https://unpkg.com/vant@4/lib/vant.min.js"></script>
    <script src="https://unpkg.com/vue3-easy-data-table@1.5.47/dist/vue3-easy-data-table.umd.js"></script>
    <script src="https://unpkg.com/echarts@5.5.1"></script>
    <script src="https://unpkg.com/vue-echarts@7.0.3"></script>
    <script src="https://unpkg.com/protobufjs@7.4.0/dist/protobuf.min.js"></script>
    <script>
        const { createApp } = Vue;
        const app = createApp({
            data() {
                return {
                    reporter: PromiseToState(loadReport),
                    activePage: 0,
                    fontWeight: '',
                    fontSize: 16,
                };
            },
            methods: {
                toGithub() {
                    window.open('https://github.com/KonghaYao/cn-font-split');
                },
            },
            async mounted() {
                const state = await this.reporter.refetch();
                this.fontWeight = state.css.weight;
            },
            computed: {
                style() {
                    const size = this.fontSize < 12 ? 12 : this.fontSize;
                    return (
                        `font-family: '${this.reporter.state?.css?.family}';` +
                        `font-weight: ${this.fontWeight};` +
                        `--van-cell-font-size: ${size}px;`
                    );
                },
            },
        });

        /** 封装Promise为状态对象 **/
        function PromiseToState(fn) {
            return {
                state: {},
                isOk() {
                    return !this.isLoading && !this.isError && this.state;
                },
                isLoading: false,
                isError: false,
                async refetch() {
                    this.isLoading = true;
                    this.isError = false;
                    try {
                        this.state = await fn();
                    } catch (e) {
                        console.error(e);
                        this.isError = true;
                    }
                    this.isLoading = false;
                    return this.state;
                },
            };
        }

        /** 载入构建出来的二进制报告文件 **/
        async function loadReport() {
            return new Promise((resolve, reject) => {
                protobuf.load('./index.proto', (err, root) => {
                    if (err) return reject(err);
                    fetch('./reporter.bin')
                        .then((res) => res.arrayBuffer())
                        .then((buf) => {
                            const OutputReport = root.lookup('OutputReport');
                            const data = OutputReport.decode(
                                new Uint8Array(buf),
                            );
                            console.log(data);
                            resolve(data);
                        })
                        .catch(reject);
                });
            });
        }

        globalThis.app = app;
        app.use(vant);
        app.component('v-chart', VueECharts);
        app.component('easy-data-table', window['vue3-easy-data-table']);
    </script>

    <!-- 汇总数据 -->
    <template id="display-chart">
        <van-cell-group inset title="构建信息">
            <van-cell title="构建工具" value="cn-font-split"></van-cell>
            <van-cell title="构建版本" :value="reporter.version"></van-cell>
            <van-cell title="构建平台" :value="reporter.platform"></van-cell>
        </van-cell-group>
        <van-cell-group inset title="构建详情">
            <div style="height: 300px; width: 400px">
                <v-chart :option="pieOptions"></v-chart>
            </div>
            <div style="height: 400px; width: 100%">
                <v-chart :option="option"></v-chart>
            </div>
        </van-cell-group>
    </template>
    <script>
        const tooltip = {
            trigger: 'axis',
            axisPointer: {
                type: 'cross',
                crossStyle: {
                    color: '#999',
                },
            },
        };
        app.component('display-chart', {
            template: '#display-chart',
            props: {
                reporter: Object,
            },
            computed: {
                option() {
                    const data = this.reporter.subsetDetail ?? [];
                    return {
                        title: {
                            text: '构建耗时',
                            x: 'center',
                        },
                        xAxis: { type: 'category' },
                        tooltip,
                        yAxis: [
                            {
                                type: 'value',

                                name: 'time / ms',
                            },
                            {
                                type: 'value',
                                name: 'bytes / KB',
                            },
                        ],
                        series: [
                            {
                                name: 'time',
                                type: 'bar',
                                data: data.map((i) => i.duration),
                            },
                            {
                                name: 'bytes',
                                type: 'line',
                                data: data.map((i) =>
                                    (i.bytes / 1024).toFixed(2),
                                ),
                            },
                        ],
                    };
                },
                pieOptions() {
                    const message = this.reporter.bundleMessage;
                    if (!message) return {};
                    return {
                        title: {
                            text: '构建大小对比',
                            x: 'center',
                        },
                        series: [
                            {
                                type: 'pie',
                                radius: ['45%', '60%'],
                                label: {
                                    formatter(b, c) {
                                        return `${b.name}\n${(
                                            b.value /
                                            (1024 * 1024)
                                        ).toFixed(2)}MB`;
                                    },
                                },
                                data: [
                                    {
                                        value: message.bundledBytes,
                                        name: 'bundled',
                                    },
                                    {
                                        value: message.originBytes,
                                        name: 'origin',
                                    },
                                ],
                            },
                            {
                                type: 'pie',
                                radius: [0, '30%'],
                                label: {
                                    formatter(b, c) {
                                        return `${b.name}\n${b.value}`;
                                    },
                                },
                                data: [
                                    {
                                        value: message.bundledSize,
                                        name: 'bundled',
                                    },
                                    {
                                        value: message.originSize,
                                        name: 'origin',
                                    },
                                ],
                            },
                        ],
                    };
                },
            },
        });
    </script>

    <!-- 字体信息表格 -->
    <template id="name-table">
        <van-cell-group inset title="CSS 信息">
            <van-cell
                title="font-family"
                :value="reporter.css?.family"
            ></van-cell>
            <van-cell
                title="font-weight"
                :value="reporter.css?.weight"
            ></van-cell>
            <van-cell
                title="font-style"
                :value="reporter.css?.style"
            ></van-cell>
            <van-cell
                title="font-display"
                :value="reporter.css?.display"
            ></van-cell>
        </van-cell-group>
        <van-cell-group inset title="字体信息">
            <easy-data-table
                :headers="columns"
                :items="reporter.nameTable??[]"
                :rows-per-page="1000"
                :body-row-class-name="useColor"
            ></easy-data-table>
        </van-cell-group>
    </template>
    <script>
        app.component('name-table', {
            template: '#name-table',
            props: {
                reporter: Object,
            },
            data() {
                return {
                    color: {
                        Windows: 'light-blue',
                        Macintosh: 'light-red',
                    },
                    columns: [
                        {
                            text: '语言',
                            value: 'language',
                            sortable: true,

                            minWidth: '36px',
                        },
                        {
                            text: '平台',
                            value: 'platform',
                            sortable: true,

                            minWidth: '20px',
                        },
                        {
                            text: '名称',
                            value: 'name',
                            sortable: true,
                            minWidth: '50px',
                        },
                        {
                            text: '值',
                            value: 'value',
                            sortable: true,
                            width: '200px',
                        },
                    ],
                };
            },
            methods: {
                useColor(item) {
                    return this.color[item.platform];
                },
            },
        });
    </script>

    <!-- 每个包的数据 -->
    <template id="pkg-list">
        <van-cell-group inset>
            <van-field
                v-model="search"
                label="搜索"
                placeholder="请输入关键字"
            ></van-field>
        </van-cell-group>

        <van-cell-group inset title="字体分包详情">
            <v-list
                ref="list"
                :items="items"
                :first-render="10"
                style="height: 80vh"
            >
                <template #default="{ item, index }">
                    <div style="padding: 0 1rem">
                        <h2 :style="{ width: item.width }">
                            ITEM: {{ index }} - {{ item.hash }}
                        </h2>
                        <span> {{String.fromCodePoint(...item.chars)}} </span>
                    </div>
                </template>
            </v-list>
        </van-cell-group>
    </template>
    <script src="https://unpkg.com/@virtual-list/vue/dist/v3/index.iife.js"></script>
    <script>
        app.component('v-list', virtualListVue);
        app.component('pkg-list', {
            template: '#pkg-list',
            props: {
                reporter: Object,
            },
            data() {
                return {
                    activeNames: [],
                    search: '',
                };
            },
            mounted() {},
            computed: {
                items() {
                    const list = this.reporter.subsetDetail ?? [];
                    if (this.search) {
                        return list.filter((i) => i.hash.includes(this.search));
                    }
                    return list;
                },
            },
        });
    </script>

    <script>
        app.mount('#app');
    </script>
</html>
